package com.retail.lottery.colalottery.job.order;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.retail.lottery.colalottery.constant.RedisConstant;
import com.retail.lottery.colalottery.entity.OrderCallback;
import com.retail.lottery.colalottery.enums.OrderCallbackStatusEnum;
import com.retail.lottery.colalottery.enums.OrderCallbackSyncStatusEnum;
import com.retail.lottery.colalottery.enums.PlatformEnum;
import com.retail.lottery.colalottery.job.node.RedisNodeIpManager;
import com.retail.lottery.colalottery.service.OrderCallbackService;
import com.retail.lottery.colalottery.utils.NetWorkUtil;
import com.retail.lottery.colalottery.utils.RedisUtils;
import com.retail.lottery.colalottery.vo.NodeInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class OrderDetailDealStrategyService extends RedisNodeIpManager {
    @Resource
    private OrderCallbackService orderCallbackService;
    @Resource
    private Map<String, OrderDetailDealStrategy> orderDetailDealStrategyMap;
    @Value("${api-bbq-client-setupId}")
    private String bbqSetupId;
    @Value("${api-bbq-meiTuan-activityTag}")
    private String meiTuanBbqActivityTag;
    @Value("${api-meiTuan-lottery-activityTag}")
    private String meiTuanLotteryActivityTag;
    @Value("${api-meiTuan-lottery-v2-activityTag}")
    private String meiTuanLotteryV2ActivityTag;
    @Value("${api-client-setupId}")
    private String lotterySetupId;
    private static final Integer ALL_CHANNEL_NUM = 2;
    private static final String MeiTuanLotterySetupCode = "cola 1";
    private static final String ALL_CHANNEL_NAME = "MT-TW";

    public void dealOrderDetail() {
        NodeInfoVo nodeInfoVo = localNodeInfo();
        int shardingTotalCount = nodeInfoVo.getNodeNum();
        int shardingItem = nodeInfoVo.getCurrentNode();
        log.info("订单回调处理Job，任务总片数: {}, 当前分片项: {}", shardingTotalCount, shardingItem);
        String redisKey = String.format(RedisConstant.REDIS_KEY_ORDER_DEAL, shardingTotalCount, shardingItem);
        if (!RedisUtils.saveNX(redisKey, "1", 30, TimeUnit.SECONDS)) {
            log.info("订单回调处理Job，任务总片数: {}, 当前分片项: {}，解析订单回调明细数据处理正在执行中，未获取锁", shardingTotalCount, shardingItem);
            return;
        }

        try {
            List<OrderCallback> orderCallbacks = orderCallbackService.getBaseMapper().selectList(new LambdaQueryWrapper<OrderCallback>()
                    .eq(OrderCallback::getStatus, OrderCallbackStatusEnum.wait_deal.getCode())
                    .last(" and id % " + shardingTotalCount + " = " + shardingItem + " order by id asc limit 100"));
            //.last(" order by id asc limit 100"));

            if (CollectionUtils.isEmpty(orderCallbacks)) {
                log.info("订单回调处理Job，任务总片数: {}, 当前分片项: {}，当前无待处理订单回调数", shardingTotalCount, shardingItem);
                return;
            }

            orderCallbacks.forEach(orderCallback -> {
                OrderDetailDealStrategy orderDetailDealStrategy = orderDetailDealStrategyMap
                        .get(PlatformEnum.getEnumByType(orderCallback.getPlatformType()).getDealValue());
                if (Objects.isNull(orderDetailDealStrategy)) {
                    log.error("订单回调处理Job，任务总片数: {}, 当前分片项: {}，订单回调数据处理异常,未找到对应的处理策略,orderCallback:{}"
                            , shardingTotalCount, shardingItem, orderCallback);
                } else {
                    orderDetailDealStrategy.dealOrderDetail(orderCallback, shardingTotalCount, shardingItem);
                }
            });

        } catch (Exception e) {
            log.error("订单回调处理Job，任务总片数: {}, 当前分片项: {}，解析订单回调明细数据处理异常，锁:{}", shardingTotalCount, shardingItem, redisKey, e);
        } finally {
            RedisUtils.del(redisKey);
        }

        log.info("订单同步Job，任务总片数: {}, 当前分片项: {}, 执行结束", shardingTotalCount, shardingItem);

    }

    public void syncOrderStatus() {
        NodeInfoVo nodeInfoVo = localNodeInfo();
        int shardingTotalCount = nodeInfoVo.getNodeNum();
        int shardingItem = nodeInfoVo.getCurrentNode();
        log.info("订单同步可乐Job，任务总片数: {}, 当前分片项: {}", shardingTotalCount, shardingItem);
        String redisKey = String.format(RedisConstant.REDIS_KEY_ORDER_SYNC, shardingTotalCount, shardingItem);
        if (!RedisUtils.saveNX(redisKey, "1", 30, TimeUnit.SECONDS)) {
            log.info("订单同步可乐Job，任务总片数: {}, 当前分片项: {}，订单数据推送可乐job处理正在执行中，未获取到锁", shardingTotalCount, shardingItem);
            return;
        }
        try {
            String lastNoticeDtStr = DateUtil.format(DateUtil.offsetMinute(new DateTime(), -5), "yyyyMMddHHmm");
            //1.查询可推送可乐当前的数据
            List<OrderCallback> orderCallbacks = orderCallbackService.getBaseMapper().selectList(new LambdaQueryWrapper<OrderCallback>()
                    .eq(OrderCallback::getStatus, OrderCallbackStatusEnum.all_ok.getCode())
                    .eq(OrderCallback::getSyncStatus, OrderCallbackSyncStatusEnum.SYNC_WAIT.getStatus())
                    .or(item -> item.eq(OrderCallback::getSyncStatus, OrderCallbackSyncStatusEnum.SYNC_AGAIN.getStatus())
                            .lt(OrderCallback::getFailNoticeDt, Long.valueOf(lastNoticeDtStr)))
                    .last(" and id % " + shardingTotalCount + " = " + shardingItem + " order by id asc limit 100"));
            //.last(" order by id asc limit 100"));
            if (CollectionUtils.isEmpty(orderCallbacks)) {
                log.info("订单同步可乐Job，任务总片数: {}, 当前分片项: {}，当前无待推送可乐数据", shardingTotalCount, shardingItem);
                return;
            }

            orderCallbacks.forEach(orderCallback -> {
                OrderDetailDealStrategy orderDetailDealStrategy = orderDetailDealStrategyMap.get(PlatformEnum.getEnumByType(orderCallback.getPlatformType()).getDealValue());
                if (Objects.isNull(orderDetailDealStrategy)) {
                    log.error("订单同步可乐Job，任务总片数: {}, 当前分片项: {}，推送可乐数据处理异常,未找到对应的处理策略,orderDetail:{}", shardingTotalCount, shardingItem, orderCallback);
                } else {
                    // 回传美团抽奖活动订单数据--当前为必回传--都可以参加抽奖活动
                    List<String> channelList = new ArrayList<>();
                    String channelType = null;
                    if (orderCallback.getActIdentifier().contains(meiTuanLotteryActivityTag)
                            || orderCallback.getActIdentifier().contains(meiTuanLotteryV2ActivityTag)) {
                        channelList.add("MT");
                    }
                    if (orderCallback.getActIdentifier().contains(meiTuanBbqActivityTag)) {
                        channelList.add("MT-CWM");
                    }
                    if (CollectionUtil.isNotEmpty(channelList)) {
                        if (channelList.size() == ALL_CHANNEL_NUM) {
                            channelType = ALL_CHANNEL_NAME;
                        } else {
                            channelType = channelList.get(0);
                        }
                    }
                    if (StringUtils.isNotBlank(channelType)) {
                        orderDetailDealStrategy.syncOrderDetail(orderCallback, channelType, lotterySetupId, shardingTotalCount, shardingItem);
                    } else {
                        orderCallback.setSyncStatus(OrderCallbackSyncStatusEnum.UN_MATCH_ACTIVITY.getStatus());
                        //未同意协议直接返回-不推送协议
                        orderCallbackService.updateById(orderCallback);
                        log.info("订单的活动标签为空:{}-区分不了渠道不进行回传", orderCallback);
                    }
                    // 回传烧烤活动订单数据
//                    if (orderCallback.getActIdentifier().contains(meiTuanBbqSetupCode)) {
//                        orderDetailDealStrategy.syncOrderDetail(orderCallback, bbqSetupId, shardingTotalCount, shardingItem);
//                    }
                }
            });

        } catch (Exception e) {
            log.error("订单数据推送可乐job异常", e);
        } finally {
            RedisUtils.del(redisKey);
        }
    }

}
